package com.hq.ims.data.utils;

import com.hq.ims.data.vo.UserMapstruct;
import com.hq.utils.exception.CommonException;
import com.hq.utils.util.JsonUtils;
import com.hq.utils.util.StringUtils;
import com.hq.web.utils.RedisUtils;

import java.time.LocalDateTime;
import java.util.Optional;

/**
 * TODO
 * <p>
 * jbp
 */
public class AccountUtils {
    /**
     * 限制登录次数
     */
    public static void limitTheNumberOfLoginErrors(String account) {
        //检测输入的账号是否为空
        StringUtils.verificationEmpty(account, ErrMsgConstant.MOBILE_VALID_ERR);
        //声明存储redis的key值
        String redisAccountErrorCountKey = RedisUtils.getLoginErrorCountKey(account);
        //根据key获取对应的登录错误次数
        String userLoginLockVoJson = JsonUtils.convertObject(RedisUtils.getRedisTemplate().opsForValue().get(redisAccountErrorCountKey), String.class);
        UserMapstruct.UserLoginLockVo userLoginLockVo = JsonUtils.stringToObject(userLoginLockVoJson, UserMapstruct.UserLoginLockVo.class);
        userLoginLockVo = Optional.ofNullable(userLoginLockVo).orElseGet(() -> {
            UserMapstruct.UserLoginLockVo userLoginLockVo1 = new UserMapstruct.UserLoginLockVo();
            userLoginLockVo1.setAccountPwdErrorCount(0);
            userLoginLockVo1.setIsLongtimeLock(false);
            return userLoginLockVo1;
        });


        LocalDateTime unLockTimme = userLoginLockVo.getUnLockTimme();
        if (unLockTimme != null && LocalDateTime.now().isBefore(unLockTimme)) {
            //相差分钟
            int diffMinute = unLockTimme.getMinute() - LocalDateTime.now().getMinute();
            diffMinute = diffMinute <= 0 ? 1 : diffMinute;
            throw CommonException.build("账号已被锁定，请在" + diffMinute + "分钟之后重试");
        }

        int cruLoginCount = userLoginLockVo.getAccountPwdErrorCount() + 1;
        userLoginLockVo.setAccountPwdErrorCount(cruLoginCount);
        if (cruLoginCount < LocalConstant.INT_NUM_FIVE) {
            RedisUtils.getRedisTemplate().opsForValue().set(redisAccountErrorCountKey, JsonUtils.objectToString(userLoginLockVo));
            //密码输错4次及以下时提示：账号密码有误
            throw CommonException.build("账号密码错误");
        } else if (
                cruLoginCount > LocalConstant.INT_NUM_FOUR &&
                        cruLoginCount < LocalConstant.INT_NUM_SEVEN
        ) {
            //如果输入错误次数超过4次小于7次
            userLoginLockVo.setUnLockTimme(LocalDateTime.now().plusMinutes(15));
            RedisUtils.getRedisTemplate().opsForValue().set(redisAccountErrorCountKey, JsonUtils.objectToString(userLoginLockVo));
            throw CommonException.build("登录失败次数过多，账号已被锁定，请15分钟之后重试");

        } else if (
                userLoginLockVo.getIsLongtimeLock() ||
                        cruLoginCount > LocalConstant.INT_NUM_SIX
        ) {
            //如果输入错误次数超过6次
            userLoginLockVo.setIsLongtimeLock(true);
            RedisUtils.getRedisTemplate().opsForValue().set(redisAccountErrorCountKey, JsonUtils.objectToString(userLoginLockVo));
            throw CommonException.build("登录失败次数已达上限，账号已被拒绝登录，请联系管理员");

        }
    }

    /**
     * 查询账号是否被锁定
     */
    public static boolean isAccountLocking(String account) {
        StringUtils.verificationEmpty(account, ErrMsgConstant.MOBILE_VALID_ERR);

        //根据账号获取redis的key值
        String loginErrorCountKey = RedisUtils.getLoginErrorCountKey(account);
        //根据key值获取value值
        String redisAccountErrorCountValue = JsonUtils.convertObject(RedisUtils.getRedisTemplate().opsForValue().get(loginErrorCountKey), String.class);
        if (!StringUtils.isEmpty(redisAccountErrorCountValue)) {
            //转换value值
            int redisAccountErrorCount = Integer.parseInt(redisAccountErrorCountValue);
            //检查账号登录错误次数是否大于5次
            if (redisAccountErrorCount >= LocalConstant.INT_NUM_FIVE) {
                return true;
            }
        }
        return false;
    }

    /**
     * 清空错误登录的次数
     */
    public static boolean deleteAccountErrorLoginCount(String account) {
        StringUtils.verificationEmpty(account, ErrMsgConstant.MOBILE_VALID_ERR);
        String loginErrorCountKey = RedisUtils.getLoginErrorCountKey(account);
        if (RedisUtils.getRedisTemplate().hasKey(loginErrorCountKey)) {
            RedisUtils.getRedisTemplate().delete(loginErrorCountKey);
            return true;
        }
        return false;
    }
}
